package main

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"fmt"
)

func main() {
	_, pri, pub := GenRsaKey(11 * 31)
	fmt.Println(pri)
	fmt.Println(pub)
	str := "1111111111111111111111111111"
	fmt.Println([]byte(str))
	data, _ := RsaEncrypt([]byte(str), pub)
	fmt.Println(data)
	data1, _ := RsaDecrypt(data, pri)
	fmt.Println(data1)
	fmt.Println(string(data1))
}

//
//func GenRsaKey(bits int) (err error,privateKey *rsa.PrivateKey,publicKey *rsa.PublicKey) {
func GenRsaKey(bits int) (err error, derStream, derPkix []byte) {
	// 生成私钥文件
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		fmt.Println(err.Error())
	}
	derStream = x509.MarshalPKCS1PrivateKey(privateKey)
	//block := &pem.Block{
	//	Type:  "RSA PRIVATE KEY",
	//	Bytes: derStream,
	//}
	//file, err := os.Create("private.pem")
	//if err != nil {
	//	fmt.Println(err.Error())
	//}
	//err = pem.Encode(file, block)
	//if err != nil {
	//	fmt.Println(err.Error())
	//}
	// 生成公钥文件
	publicKey := &privateKey.PublicKey
	derPkix, err = x509.MarshalPKIXPublicKey(publicKey)
	//if err != nil {
	//	fmt.Println(err.Error())
	//}
	//block = &pem.Block{
	//	Type:  "PUBLIC KEY",
	//	Bytes: derPkix,
	//}
	//file, err = os.Create("public.pem")
	//if err != nil {
	//	fmt.Println(err.Error())
	//}
	//err = pem.Encode(file, block)
	//if err != nil {
	//	fmt.Println(err.Error())
	//}
	return
}

// 加密
func RsaEncrypt(origData, publicKey []byte) ([]byte, error) {
	//block, _ := pem.Decode(publicKey)
	//if block == nil {
	//	return nil, errors.New("public key error")
	//}
	pubInterface, err := x509.ParsePKIXPublicKey(publicKey)
	if err != nil {
		return nil, err
	}
	pub := pubInterface.(*rsa.PublicKey)
	return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}

// 解密
func RsaDecrypt(ciphertext, privateKey []byte) ([]byte, error) {
	//block, _ := pem.Decode(privateKey)
	//if block == nil {
	//	return nil, errors.New("private key error!")
	//}
	priv, err := x509.ParsePKCS1PrivateKey(privateKey)
	if err != nil {
		return nil, err
	}
	return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}
func Sign(src []byte, hash crypto.Hash, priv *rsa.PrivateKey) ([]byte, error) {
	h := hash.New()
	h.Write(src)
	hashed := h.Sum(nil)
	return rsa.SignPKCS1v15(rand.Reader, priv, hash, hashed)
}

func Verify(src []byte, sign []byte, hash crypto.Hash, pub *rsa.PublicKey) error {
	h := hash.New()
	h.Write(src)
	hashed := h.Sum(nil)
	return rsa.VerifyPKCS1v15(pub, hash, hashed, sign)
}
